package com.gome.boot.common.util;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

import java.lang.reflect.Method;

/**
 * 包路径扫描工具类.
 *
 * @author baoxiufeng
 */
public class PackageScanUtils {

    /**
     * 扫描指定包路径下的指定类.
     *
     * @param beanFactory  对象实例化工厂注册器
     * @param scanClazz    要扫描的类型
     * @param scanPackages 扫描类所在包路径列表
     */
    public static void scan(BeanDefinitionRegistry beanFactory, Class scanClazz, String... scanPackages) {
        Assert.notEmpty(scanPackages, "The scan packages must not be empty.");
        try {
            Class clazz = ClassUtils.forName("org.springframework.context.annotation.ClassPathBeanDefinitionScanner", null);
            Object scanner = clazz.getConstructor(new Class[]{BeanDefinitionRegistry.class, Boolean.TYPE}).newInstance(new Object[]{beanFactory, Boolean.valueOf(true)});
            Class filterClass = ClassUtils.forName("org.springframework.core.type.filter.AnnotationTypeFilter", null);
            Object filter = filterClass.getConstructor(new Class[]{Class.class}).newInstance(new Object[]{scanClazz});
            Method addIncludeFilter = clazz.getMethod("addIncludeFilter", new Class[]{ClassUtils.forName("org.springframework.core.type.filter.TypeFilter", null)});
            addIncludeFilter.invoke(scanner, new Object[]{filter});
            Method scan = clazz.getMethod("scan", new Class[]{String[].class});
            scan.invoke(scanner, new Object[]{scanPackages});
        } catch (Throwable e) {
            ;
        }
    }
}
